<template>
  <v-container fluid>
    <v-row justify="start">
      <v-col
        cols="12"
        md="12"
      >
        <v-alert
          :type="alertType"
          dense
          icon="mdi-monitor-dashboard"
        >
          <v-row
            class="mt-1"
            dense
          >
            {{ lanChar.status.ImmeLogOutput }}
            <v-btn
              class="mx-0 mt-n1"
              fab
              icon
              x-small
              color="primary"
              @click="wsReconn()"
            >
              <v-icon>mdi-cached</v-icon>
            </v-btn>
            <v-spacer />
            <v-select
              v-model="svc"
              class="mt-n1"
              style="width: 10px"
              outlined
              dense
              hide-details
              :items="filter.svcs"
              :label="lanChar.status.SvcInstance"
              :hint="lanChar.status.SvcInstanceSelectHint"
            />
          </v-row>
        </v-alert>
        <v-row
          dense
          align="center"
        >
          <v-col
            cols="12"
            md="6"
          >
            <v-select
              v-model="levels"
              :items="filter.levels"
              :menu-props="{ maxHeight: '400' }"
              label="Level"
              multiple
              dense
              hint="Select Level"
              outlined
              chips
            />
          </v-col>
          <v-spacer />
          <v-col
            cols="12"
            md="6"
          >
            <v-select
              v-model="modules"
              :items="filter.modules"
              :menu-props="{ maxHeight: '400' }"
              multiple
              outlined
              dense
              chips
              hint="Select Modules"
              label="Modules"
            />
          </v-col>
        </v-row>
        <v-textarea
          v-model="printText"
          clearable
          outlined
          dense
          clear-icon="mdi-close-circle"
          color="orange orange-darken-4"
          background-color="amber lighten-4"
          rows="40"
          row-height="6"
          :auto-grow="autoGrow"
          :label="lanChar.status.ImmeLogOutput"
        />
        <div class="py-6" />
      </v-col>
    </v-row>
    <material-snackbar-tip
      v-model="snackbarDescp.snackbar"
      :type="snackbarDescp.snackbarType"
      :timeout="snackbarDescp.snackbarTimeout"
      v-bind="{
        bottom: true,
        right: true
      }"
      :text="snackbarDescp.snackbarContent"
    />
  </v-container>
</template>

<script>
  import * as wso from '@/util/ws'
  import globalDef from '@/util/globals'
  import lan from '@/util/lan-char'
  import { get } from 'vuex-pathify'
  export default {
    name: 'ImmLog',
    props: {
      header: {
        type: Boolean,
        required: false,
        default: true,
      },
    },
    data: () => ({
      snackbarDescp: {
        snackbar: false,
        snackbarContent: 'snackbar content',
        snackbarTimeout: 2000,
        snackbarType: 'info',
      },
      lanChar: lan.GetLan(),
      alertType: 'success',
      autoGrow: false,
      printText: '',
      levels: [
        'debug',
        'info',
        'warn',
        'error',
      ],
      modules: [''],
      svc: '',
      svcs: {},
      filter: {
        levels: [
          'debug',
          'info',
          'warn',
          'error',
        ],
        modules: [],
        svcs: [],
      },
      ws: null,
      immeLogSerialNum: 0,
      svcGetAllSerialNum: 0,
      svcUpdateSubReqSerialNum: 0,
    }),
    computed: {
      ...get('user', [
        'token',
      ]),
    },
    watch: {
      svc (val, oldVal) {
        if (val === oldVal) return
        this.endImmeLog(oldVal)
        this.startImmeLog(val)
      },
    },
    created () {
      globalDef.VueObject.$on('lanChange', lanChar => {
        this.lanChar = lanChar
      })

      var loc = (window.location + '').split('/')
      const url = 'ws://' + loc[2] + `/svclog/v1/ws?token=${this.token}`
      this.ws = wso.wsConn(url, this.wsOnopen, this.wsMsgHandler, this.wsOnclose)
      console.log('this.ws=', this.ws)
    },
    mounted () {
    },
    beforeDestroy () {
      wso.wsClose(this.ws)
    },
    methods: {
      tipInfo (level, content, timeout) {
        this.snackbarDescp.snackbarType = level
        this.snackbarDescp.snackbarContent = content
        this.snackbarDescp.snackbarTimeout = timeout
        this.snackbarDescp.snackbar = true
      },
      getSvcAll () {
        this.svcGetAllSerialNum++
        const data = {
          msgHead: {
            instanceID: 'apptpl-web-ui-client',
            resOrReq: 'req',
            requestType: 'svc-get-all',
            serialNum: this.svcGetAllSerialNum,
          },
        }
        wso.wsSend(this.ws, data)
      },
      startImmeLog (id) {
        this.immeLogSerialNum++
        const data = {
          msgHead: {
            instanceID: 'apptpl-web-ui-client',
            resOrReq: 'req',
            requestType: 'start-imme-log',
            serialNum: this.immeLogSerialNum,
          },
          data: {
            instanceID: id,
          },
        }
        wso.wsSend(this.ws, data)
        console.log('startImmeLog, id=', id)
      },
      endImmeLog (id) {
        this.immeLogSerialNum++
        const data = {
          msgHead: {
            instanceID: 'apptpl-web-ui-client',
            resOrReq: 'req',
            requestType: 'end-imme-log',
            serialNum: this.immeLogSerialNum,
          },
          data: {
            instanceID: id,
          },
        }
        wso.wsSend(this.ws, data)
        console.log('endImmeLog, id=', id)
      },
      filterLine (line) {
        // patch modules
        if (this.filter.modules.indexOf(line.module) === -1) {
          this.filter.modules.push(line.module)
        }

        // apply filters
        if (this.levels.indexOf(line.level) === -1) {
          return null
        }
        if (this.modules.indexOf(line.module) === -1) {
          return null
        }
        return line
      },
      svcUpdateSub () {
        this.svcUpdateSubReqSerialNum++
        const data = {
          msgHead: {
            instanceID: 'apptpl-web-ui-client',
            resOrReq: 'req',
            requestType: 'svc-update-sub',
            serialNum: this.svcUpdateSubReqSerialNum,
          },
        }
        wso.wsSend(this.ws, data)
      },
      svcUpdateUnSub () {
        this.svcUpdateSubReqSerialNum++
        const data = {
          msgHead: {
            instanceID: 'apptpl-web-ui-client',
            resOrReq: 'req',
            requestType: 'svc-update-unsub',
            serialNum: this.svcUpdateSubReqSerialNum,
          },
        }
        wso.wsSend(this.ws, data)
      },
      wsOnopen () {
        this.getSvcAll()
        this.svcUpdateSub()
      },
      wsOnclose () {
        this.endImmeLog(this.svc)
        this.svcUpdateUnSub()
      },
      wsReconn () {
        this.ws = wso.wsReconn(this.ws, () => {
          this.startImmeLog(this.svc)
        }, this.wsMsgHandler, this.wsOnclose)
      },
      wsMsgHandler (data) {
        var v = data && JSON.parse(data.data)
        if (v.msgHead !== undefined && v.msgHead.resOrReq !== undefined) {
          switch (v.msgHead.resOrReq) {
            case 'req':
              this.wsReqHandler(v)
              break
            case 'res':
              this.wsResHandler(v)
              break
            default:
              break
          }
        }
      },
      wsReqHandler (v) {
        switch (v.msgHead.requestType) {
          case 'imme-log-out':
            if (v.data !== undefined && v.data !== null) {
              for (var line of v.data) {
                var fline = this.filterLine(line)
                if (fline !== null) {
                  this.printText += line.time + ' [ ' + line.level + ' ] ' + 'M: ' + line.module + ' [' + line.file + '] ' + line.msg + '\n'
                }
              }
            }
            break

          case 'svc-update-pub':
            if (v.msgHead.status === 'ok') {
              v.data.svcUpdateInfo.forEach(e => {
                const index = this.filter.svcs.indexOf(e.instanceID)
                if (index === -1) {
                  if (e.action === 'on') {
                    this.filter.svcs.push(e.instanceID)
                  }
                } else {
                  if (e.action === 'off') {
                    this.filter.svcs.splice(index, 1)
                  }
                }
              })
            }
            break

          default:
            break
        }
      },
      wsResHandler (v) {
        switch (v.msgHead.requestType) {
          case 'svc-get-all':
            if (v.msgHead.status === 'ok' && v.msgHead.serialNum === this.svcGetAllSerialNum) {
              this.svcs = v.data
              this.filter.svcs = []
              for (const k in this.svcs) {
                this.filter.svcs.push(k)
              }
              if (this.filter.svcs.length >= 0 && this.svc === '') {
                this.svc = this.filter.svcs[0]
              }
            }
            break

          default:
            break
        }
      },
    },
  }

</script>
